/*
 * @Description:
 * @Version: 2.0
 * @Autor: wiz
 * @Date: 2023-05-30 15:51:40
 * @LastEditors: swc
 * @LastEditTime: 2024-11-27 17:50:40
 */
import {
  N_oBaseGrid,
  N_oBasePanel,
  N_oInteraction,
  N_oSetupPanel
} from '@/types';
import { EDIT_STATE, Tsrv, ifs, ts, vxeConfig } from './config';

class T_command {
  private oBasePanel: N_oBasePanel.oBasePanel;

  private compBox: ifs.I_compBox;

  private compID: string;

  private compName: string;

  private _editorState: EDIT_STATE; // 编译状态

  private _formsNum: number = 0; // 表单数

  private formsInstance: Map<string, any> = new Map<string, any>();

  private searchFormsInstance: Map<string, any> = new Map<string, any>();

  private tablesInstance: Map<string, any> = new Map<string, any>();

  // 组件配合 在外部实例化
  private TCoordination: ifs.I_compCoordination;

  // 临时存储toolbar状态
  private toolbarStatusBak: any = null;

  // 已被其它人锁定 key =  _sys_edit_lock.f_code
  public editLocked: Set<string> = new Set();

  // 本操作锁定持有的锁
  public editLockNum: Map<
    string,
    {
      funID: string;
      cmd: 'lock' | 'unLock';
      rowID: string;
      key: string;
    }
  > = new Map();

  constructor(self: any, compBoxInfo: ifs.I_compBoxInfo) {
    this.oBasePanel = self;
    this.compBox = compBoxInfo.TcompBox;
    this.compID = compBoxInfo.compID;
    this.compName = self.G_compName;
    this._editorState = EDIT_STATE.BROWSE;
  }

  public set editorState(p: EDIT_STATE) {
    this._editorState = p;
    this.handleEditorStateChange(this._editorState);
    // this.setEditorState();
  }

  public get editorState(): EDIT_STATE {
    return this._editorState;
  }

  // private setEditorState() {
  //   switch (this._editorState) {
  //     case EDIT_STATE.BROWSE:
  //       break;
  //     case EDIT_STATE.NEW:
  //       break;
  //     case EDIT_STATE.MODIFY:
  //       break;
  //     default:
  //       throw Error('不能识别的状态');
  //   }
  // }

  private setForm() {
    const oBasePanel = this.oBasePanel;
    // 设置form的名称
    oBasePanel.name.formName = oBasePanel.config.name;
    if (
      // oBasePanel.config.originComp === 'custom' &&
      // oBasePanel.config.originName !== ''
      !Tsrv.noValue(oBasePanel.config.refTable)
    ) {
      // oBasePanel.name.formName = oBasePanel.config.originName;
      oBasePanel.name.formName = oBasePanel.config.refTable;
      oBasePanel.funName.formName = oBasePanel.config.name;
    } else {
      oBasePanel.name.formName = oBasePanel.config.name;
      oBasePanel.funName.formName = oBasePanel.config.name;
    }
    // form的配置
    oBasePanel.forms = oBasePanel.config.formPanels;

    oBasePanel.isPanelSingle =
      Tsrv.utils.filter(oBasePanel.forms, el => !el.content.formStyle.isBottom)
        .length === 1;
    this._formsNum = oBasePanel.forms.length;
  }

  public get formsNum(): number {
    return this._formsNum;
  }

  private setTable() {
    const oBasePanel = this.oBasePanel;
    // table的配置
    oBasePanel.tables = oBasePanel.config.tablePanels;
    oBasePanel.tablesLength = oBasePanel.tables.length;

    oBasePanel.tables.forEach(el => {
      if (
        // oBasePanel.config.originComp === 'custom' &&
        // oBasePanel.config.originName !== ''
        !Tsrv.noValue(oBasePanel.config.refTable)
      ) {
        oBasePanel.funName.tableNames.push(el.label);
        // oBasePanel.name.tableNames.push(el.content.originName);
        oBasePanel.name.tableNames.push(el.content.refTable);
      } else {
        oBasePanel.funName.tableNames.push(el.label);
        oBasePanel.name.tableNames.push(el.label);
      }
    });
    oBasePanel.setActions(oBasePanel.config.action); // actions
  }

  // 初始化状态
  private initToolbar() {
    this.oBasePanel.toolbar.previous.isDisable = true;
    this.oBasePanel.toolbar.jumpFirst.isDisable = true;
    this.oBasePanel.toolbar.next.isDisable = true;
    this.oBasePanel.toolbar.jumpLast.isDisable = true;

    this.oBasePanel.toolbar.save.isDisable = true;
    this.oBasePanel.toolbar.edit.value = true;
    this.oBasePanel.config?.audit?.hasRequestAudit &&
      (this.oBasePanel.config.audit.hasRequestAudit = true);
    this.oBasePanel.toolbar.delete.isDisable = true;

    this.oBasePanel.toolbar.insert.isDisable = true;
    this.oBasePanel.toolbar.edit.isDisable = true;
    this.oBasePanel.toolbar.refresh.isDisable = true;
    this.setToolbarStatus('selbill', 'isDisable', true);
    this.oBasePanel.toolbar.audit.isDisable = true;
  }

  private setToolbar() {
    const oBasePanel = this.oBasePanel;
    // toolbar的配置
    oBasePanel.toolbar = vxeConfig.getToolbarConfig(
      oBasePanel.config.toolbar,
      'basepanel'
    );
    this.initToolbar();
    if (oBasePanel.config.queryLink && oBasePanel.config.queryLink.length > 0)
      oBasePanel.toolbar['queryLink'] = oBasePanel.config.queryLink;
    if (oBasePanel.config.selbill && oBasePanel.config.selbill.length > 0)
      oBasePanel.toolbar['selbill'] = oBasePanel.config.selbill;
    oBasePanel.toolbar.edit.value = false;
    if (oBasePanel.config.audit) {
      oBasePanel.hasRequestAudit =
        oBasePanel.config.audit.hasRequestAudit === true;
    }
    // 送审根据功能配置来
    // oBasePanel.toolbar.requestAudit.isDisable = !oBasePanel.hasRequestAudit;
    // oBasePanel.toolbar.auditStatus.isDisable = !oBasePanel.hasRequestAudit;

    const toolbarPermission = Tsrv.utils.find(
      oBasePanel.config.permission,
      el =>
        el.area === 'toolbar' &&
        (el.type === 'button' || el.type === 'NULL') &&
        el.data.insert !== undefined
    );

    if (toolbarPermission) {
      const data = toolbarPermission.data;
      for (const key in oBasePanel.toolbar) {
        if (data[key]) {
          oBasePanel.toolbar[key].auth = !!data[key];
        }
      }
    }

    const customPermission = Tsrv.utils.find(
      oBasePanel.config.permission,
      el => el.area === 'toolbar' && el.type === 'customButton'
    );
    this.oBasePanel.customPermission = customPermission;
    if (
      customPermission &&
      oBasePanel.toolbar['addon'] &&
      oBasePanel.toolbar['addon'].length > 0
    ) {
      const data = customPermission.data;
      oBasePanel.toolbar['addon'].forEach(el => {
        el.auth = !!data[el.title];
        if (el.children.length > 0) {
          el.children.forEach(child => {
            child.auth = !!data[child.title];
          });
        }
        if (el?.initDisabled === true) {
          el.auth = false;
        }
        if (el?.initNotshow === true) {
          el.isShow = false;
        }
      });
      // 获取永久储存自定义按钮状态的按钮————并初始化更新状态  （功能打开时、刷新时、）
      this.getCustBtnStatus();
    }

    const selbillPermission = Tsrv.utils.find(
      oBasePanel.config.permission,
      el => el.area === 'toolbar' && el.type === 'selbill'
    );
    if (
      selbillPermission &&
      oBasePanel.toolbar['selbill'] &&
      oBasePanel.toolbar['selbill'].length > 0
    ) {
      const data = selbillPermission.data;
      oBasePanel.toolbar['selbill'].forEach(el => {
        el.auth = !!data[el.id];
      });
    }
    oBasePanel.toolbar.bancodeScan = {
      auth: true,
      isDisable: false,
      isShow: Tsrv.getx(oBasePanel.config, 'bancodeScan.enable', false),
      value: null
    };
  }

  private setPms() {
    const oBasePanel = this.oBasePanel;
    // 权限控制表格列
    if (this.oBasePanel.useTable) {
      const tpms = oBasePanel.tables[0].content;
      const tablePermission = Tsrv.utils.find(
        tpms.permission,
        el => el.area === 'table'
      );
      if (tablePermission) {
        const tdata = tablePermission.data;
        for (const item in tdata) {
          const key = Tsrv.utils.find(
            tpms.tableColumns,
            el => el.field === item
          );
          if (key && !!tdata[item] === false) {
            key.isShow = false;
          }
        }
      }
    }

    // 权限控制表单列
    const fpms = oBasePanel.forms[0].content;
    const formPermission = Tsrv.utils.find(
      oBasePanel.config.permission,
      el => el.area === 'form'
    );
    if (formPermission) {
      const fdata = formPermission.data;
      for (const item in fdata) {
        const key = Tsrv.utils.find(fpms.formColumns, el => el.field === item);
        if (key && !!fdata[item] === false) {
          key.isShow = false;
        }
      }
    }
  }

  public init(userTable: boolean) {
    this.setForm();
    userTable && this.setTable();
    this.setToolbar();
    this.setPms();
  }

  public regInstance(compBoxInfo: ifs.I_compBoxInfo, typ: string, key: string) {
    const compID = compBoxInfo.compID;
    const compBox = compBoxInfo.TcompBox;
    if (typ === 'form') {
      this.formsInstance.set(
        key,
        compBox.getCompMergeName(compID, 'oBaseForm')
      );
    } else if (typ === 'table') {
      this.tablesInstance.set(
        key,
        compBox.getCompMergeName(compID, 'oBaseGrid')
      );
    } else if (typ === 'searchForm') {
      this.searchFormsInstance.set(
        key,
        compBox.getCompMergeName(compID, 'oBaseForm')
      );
    } else {
      throw new Error(`Unrecognized type[${typ}]`);
    }
  }

  public getFormInstance(key: number | string) {
    return this.formsInstance.get(`${key}`);
  }

  public getSearchFormInstance(key: number | string) {
    return this.searchFormsInstance.get(`${key}`);
  }

  public getTableInstance(key: string | number): any {
    return this.tablesInstance.get(`${key}`);
  }

  public setLoadForomDataBtnState() {
    this.oBasePanel.toolbar.insert.isDisable = false;
    this.oBasePanel.toolbar.edit.isDisable = false;
    this.oBasePanel.toolbar.refresh.isDisable = false;
    this.oBasePanel.toolbar.audit.isDisable = false;
  }

  /**
   * setToolbarStatus 设置toolbar的状态
   */
  public setToolbarStatus(name: string, key: string, value: boolean) {
    vxeConfig.setLevelParams(this.oBasePanel.toolbar, name, key, value);
  }

  /**
   * 设置是否可修改
   */
  public setModify(value: boolean) {
    for (let i = 0; i < this.formsNum; i++) {
      const form = this.getFormInstance(i);
      form.setModify(value);
    }
    this.oBasePanel.name.tableNames.forEach((name, index) => {
      const table = this.getTableInstance(index);
      table.setModify(value);
      table.setToolbarStatus('insert', 'isDisable', !value);
      table.setToolbarStatus('delete', 'isDisable', !value);
    });
  }

  public setInsertBtnState() {
    // this.oBasePanel.toolbar.delete.isDisable = true;
    this.oBasePanel.toolbar.delete.isDisable = false;
    this.oBasePanel.toolbar.next.isDisable = true;
    this.oBasePanel.toolbar.jumpLast.isDisable = true;
    this.oBasePanel.toolbar.previous.isDisable = true;
    this.oBasePanel.toolbar.jumpFirst.isDisable = true;
    this.oBasePanel.toolbar.insert.isDisable = true;
    this.oBasePanel.toolbar.edit.isDisable = true;
    this.oBasePanel.toolbar.refresh.isDisable = false;
    this.setToolbarStatus('selbill', 'isDisable', false);
    this.oBasePanel.toolbar.audit.isDisable = true;
    this.oBasePanel.toolbar.requestAudit.isDisable = true;
    this.oBasePanel.toolbar.save.isDisable = true;
    this.oBasePanel.tagsControl.audit = false;
  }

  public getBpaHeadUpdRec(): ifs.I_bpaHeadUpdRec {
    const o = new ts.T_bpaHeadUpdRec();
    const updateRecords: ifs.I_fv[] = [];
    // 表字段分布在多个form
    for (let i = 0; i < this.formsNum; i++) {
      const updateData = this.getFormInstance(i).getUpdateData();
      updateData.forEach(el => {
        if (!Tsrv.utils.find(updateRecords, item => item.field === el.field)) {
          updateRecords.push(el);
        }
      });
    }
    o.setDataRule({} as ifs.I_rule).setFileInfo({});
    o.setRowData(...updateRecords);
    const f = new ts.T_filter();
    o.filter = f.parseEQ('id', this.oBasePanel.formID);
    // 加入 bpa操作 前后事件
    const actionsCfg = this.oBasePanel.actionsCfg;
    // const syncParams = new ts.T_syncParams();
    // const records = [];
    const rowData = { id: this.oBasePanel.formID };
    updateRecords.forEach(el => {
      rowData[el.field] = el.value;
    });
    const p = {
      funName: this.oBasePanel.funName.formName,
      from: '',
      data: {
        id: this.oBasePanel.formID,
        updateRecords: [rowData]
      }
    };
    if (actionsCfg.beforeEdit) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'beforeEdit';
      syncParams
        .setApiName(actionsCfg.beforeEdit)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setBefEvent(syncParams);
    }
    if (actionsCfg.afterEdit) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'afterEdit';
      syncParams
        .setApiName(actionsCfg.afterEdit)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setAftEvent(syncParams);
    }
    return o;
  }

  public getBpaHeadInsRec(): ifs.I_bpaHeadInsRec {
    const o = new ts.T_bpaHeadInsRec();
    const insertRecords: Array<ifs.I_fv> = [];
    for (let i = 0; i < this.formsNum; i++) {
      const insertData = this.getFormInstance(i).getData();
      insertData.forEach(el => {
        if (!Tsrv.utils.find(insertRecords, item => item.field === el.field)) {
          insertRecords.push(el);
        }
      });
    }
    if (this.oBasePanel.formID && this.oBasePanel.formID !== 0) {
      insertRecords.push({
        field: 'id',
        value: this.oBasePanel.formID
      } as ifs.I_fv);
    }

    o.setDataRule({} as ifs.I_rule).setFileInfo({});
    o.setRowData(...insertRecords);
    // 加入 bpa操作 前后事件
    const actionsCfg = this.oBasePanel.actionsCfg;
    // const syncParams = new ts.T_syncParams();
    const insRow = { id: this.oBasePanel.formID };
    insertRecords.forEach(el => {
      insRow[el.field] = el.value;
    });
    const p = {
      funName: this.oBasePanel.funName.formName,
      from: '',
      data: { id: this.oBasePanel.formID, insertRecords: insRow }
    };
    if (actionsCfg.beforeInsert) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'beforeInsert';
      syncParams
        .setApiName(actionsCfg.beforeInsert)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setBefEvent(syncParams);
    }
    if (actionsCfg.afterInsert) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'afterInsert';
      syncParams
        .setApiName(actionsCfg.afterInsert)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setAftEvent(syncParams);
    }
    return o;
  }

  public getBpaHeadDelRec(): ifs.I_bpaHeadDelRec {
    const o = new ts.T_bpaHeadDelRec();
    o.filter = { id: { $eq: this.oBasePanel.formID } };
    this.oBasePanel.funName.tableNames.forEach((name, index) => {
      const oBaseGrid = this.getTableInstance(index);
      const scope = oBaseGrid.getScope();
      const filter = {};
      filter[scope.field] = { $eq: this.oBasePanel.formID };
      o.mto.push({
        rule: {} as ifs.I_rule,
        tableName: name,
        dbType: oBaseGrid.GT_editor.getDbType(),
        filter
      });
    });
    // 加入 bpa操作 前后事件
    const actionsCfg = this.oBasePanel.actionsCfg;
    // const syncParams = new ts.T_syncParams();
    const p = {
      funName: this.oBasePanel.funName.formName,
      from: '',
      data: [this.oBasePanel.formID]
    };
    if (actionsCfg.beforeDelete) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'beforeDelete';
      syncParams
        .setApiName(actionsCfg.beforeDelete)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setBefEvent(syncParams);
    }
    if (actionsCfg.afterDelete) {
      const syncParams = new ts.T_syncParams();
      const _p = Tsrv.utils.clone(p, true);
      _p.from = 'afterDelete';
      syncParams
        .setApiName(actionsCfg.afterDelete)
        .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
        .setFunInfo(
          Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
        )
        .setSyncData(_p);
      o.setAftEvent(syncParams);
    }
    return o;
  }

  public getBpaHead(): ifs.I_bpaHead {
    const o = new ts.T_bpaHead();
    if (this.editorState === EDIT_STATE.NEW) {
      o.setInsertRec(this.getBpaHeadInsRec());
    } else if (this.editorState === EDIT_STATE.MODIFY) {
      o.setUpdateRec(this.getBpaHeadUpdRec());
    } else if (this.editorState === EDIT_STATE.DELETE) {
      // o.setUpdateRec(this.getBpaHeadUpdRec());
      o.setRemoveRec(this.getBpaHeadDelRec());
    }

    o.setFunName(this.oBasePanel.funName.formName);
    // 一张表分布在不同的form中。
    const dbType = this.getFormInstance(0).getDbType();
    o.setLang(this.oBasePanel.$i18n.locale).setDbType(dbType);
    o.setTableName(this.oBasePanel.name.formName);
    return o;
  }

  public getBpaBodyInsRec(
    res: Array<any>,
    scope: object,
    name: string,
    actionsCfg: any
  ): ifs.I_bpaBodyInsRec {
    const o = new ts.T_bpaBodyInsRec();
    o.setScope(scope);
    if (Tsrv.utils.noValue(res)) {
      o.data = [];
    } else {
      res.forEach(el => {
        const d = new ts.T_baseData();
        d.setRowData(...(el as ifs.I_fv[]));
        d.fileInfo = {};
        d.rule = {} as ifs.I_rule;
        o.data.push(d);
      });
      // 加入 前后事件
      const p = {
        funName: name,
        from: '',
        data: { billId: this.oBasePanel.formID, insertRecords: res }
      };
      if (actionsCfg.beforeInsert) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'beforeInsert';
        syncParams
          .setApiName(actionsCfg.beforeInsert)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        o.setBefEvent(syncParams);
      }
      if (actionsCfg.afterInsert) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'afterInsert';
        syncParams
          .setApiName(actionsCfg.afterInsert)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        o.setAftEvent(syncParams);
      }
    }

    return o;
  }

  public getBpaBodyUpdRec(
    res: ifs.I_fv[][],
    name: string,
    actionsCfg: any
  ): ifs.I_bpaBodyUpdRec {
    const o = new ts.T_bpaBodyUpdRec();
    // o.setAftEvent
    // o.setBefEvent
    if (Tsrv.utils.noValue(res)) {
      o.data = [];
    } else {
      res.forEach(itm => {
        const filter = { id: { $eq: '' } };
        itm.forEach(el => {
          if (el.field === 'id') {
            filter.id.$eq = el.value.toString();
          }
        });
        o.setData(
          {},
          filter,
          {} as ifs.I_rule,
          ...itm.filter(el => el.field !== 'id')
        );
      });
      // 加入 前后事件
      const updateRecords = [];
      res.forEach(ele => {
        const rowData = {};
        ele.forEach(item => {
          rowData[item.field] = item.value;
        });
        updateRecords.push(rowData);
      });
      const p = {
        funName: name,
        from: '',
        data: { billId: this.oBasePanel.formID, updateRecords }
      };
      if (actionsCfg.beforeEdit) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'beforeEdit';
        syncParams
          .setApiName(actionsCfg.beforeEdit)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        // ctd.setUpdRecBefSync([syncParams]);
        o.setBefEvent(syncParams);
      }
      if (actionsCfg.afterEdit) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'afterEdit';
        syncParams
          .setApiName(actionsCfg.afterEdit)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        // ctd.setUpdRecAftSync([syncParams]);
        o.setAftEvent(syncParams);
      }
    }

    return o;
  }

  public getBpaBodyDelRec(
    res,
    name: string,
    actionsCfg: any
  ): ifs.I_bpaBodyDelRec {
    const o = new ts.T_bpaBodyDelRec();
    // if (Tsrv.utils.noValue(res)) {
    //   o.filter = {};
    // }
    if (Tsrv.utils.noValue(res)) {
      return undefined;
    }
    if (Array.isArray(res)) {
      let isErr: boolean = false;
      res.forEach(id => {
        if (typeof id !== 'string') {
          isErr = true;
        }
      });
      if (!isErr) {
        o.filter = { id: { $in: res } };
      }
      // 加入 前后事件
      const p = {
        funName: name,
        from: '',
        data: { billId: this.oBasePanel.formID, removeRecords: res }
      };
      if (actionsCfg.beforeDelete) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'beforeDelete';
        syncParams
          .setApiName(actionsCfg.beforeDelete)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        o.setBefEvent(syncParams);
      }
      if (actionsCfg.afterDelete) {
        const syncParams = new ts.T_syncParams();
        const _p = Tsrv.utils.clone(p, true);
        _p.from = 'afterDelete';
        syncParams
          .setApiName(actionsCfg.afterDelete)
          .setUserInfo(Tsrv.getUserInfo() as ifs.I_userInfo)
          .setFunInfo(
            Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo
          )
          .setSyncData(_p);
        o.setAftEvent(syncParams);
      }
    } else {
      throw new Error('获取单身删除ID失败');
    }
    return o;
  }

  public getBpaBody(): ifs.I_bpaBody {
    const o = new ts.T_bpaBody();
    o.rule = {} as ifs.I_rule;
    this.oBasePanel.funName.tableNames.forEach((name: string, index) => {
      const oBaseGrid = this.getTableInstance(index);
      const scope: ifs.I_fv = oBaseGrid.getScope();
      const dbType = oBaseGrid.getDbType();
      const changes = oBaseGrid.getChanges();
      const actionsCfg = oBaseGrid.GT_editor.actionsCfg;
      o.data.push({
        tableName: name,
        dbType,
        insertRecords: this.getBpaBodyInsRec(
          changes.insertRecords,
          scope,
          name,
          actionsCfg
        ),
        updateRecords: this.getBpaBodyUpdRec(
          changes.updateRecords,
          name,
          actionsCfg
        ),
        removeRecords: this.getBpaBodyDelRec(
          changes.removeRecords,
          name,
          actionsCfg
        )
      });
    });
    return o;
  }

  public setSaveState() {
    let flag: boolean = true;
    const o = this.getBpa();
    if (
      !Tsrv.utils.noValue(o.head?.insertRecords?.rowData) ||
      !Tsrv.utils.noValue(o.head?.updateRecords?.rowData) ||
      !Tsrv.utils.noValue(o.head?.removeRecords?.mto)
    ) {
      flag = false;
    }

    if (!Tsrv.utils.noValue(o.body?.data)) {
      for (let i = 0; i < o.body?.data.length; i++) {
        if (
          // !Tsrv.utils.noValue(o.body.data[i].insertRecords?.setData) ||
          // !Tsrv.utils.noValue(o.body.data[i].updateRecords?.setData) ||
          // !Tsrv.utils.noValue(o.body.data[i].removeRecords?.filter)
          !Tsrv.utils.noValue(o.body.data[i].insertRecords?.data) ||
          !Tsrv.utils.noValue(o.body.data[i].updateRecords?.data) ||
          !Tsrv.utils.noValue(o.body.data[i].removeRecords?.filter)
        ) {
          flag = false;
          break;
        }
      }
    }
    this.oBasePanel.toolbar.save.isDisable = flag;
  }

  public getBpa(): ifs.I_bpaArg {
    const bpa = new ts.T_bpaArg();
    return bpa.setHead(this.getBpaHead()).setBody(this.getBpaBody());
  }

  // 单行加解销，全布解锁 unLockAll 一般只用加锁
  public handleEditLock(row: any, cmd: 'lock' | 'unLock'): Promise<boolean> {
    return new Promise((resole, reject) => {
      if (this.editorState === EDIT_STATE.MODIFY) {
        let funID = ``;
        const key = row.id;
        if (this.oBasePanel.config.status === 'main') {
          funID = Tsrv.getMinFunID(this.oBasePanel.config.mainFun);
        } else {
          funID = Tsrv.getDeputyFunID(
            this.oBasePanel.config.mainFun,
            this.oBasePanel.config.name
          );
        }
        if (!this.editLockNum.has(row.id)) {
          this.apiEditLock({ funID, key, rowID: row.id, cmd })
            .then(([res, err]) => {
              // console.info(err ?? res.msg);
              if (err) {
                resole(false);
              }
              if (!res.success) {
                // this.oBaseGrid.$msg(res.msg);
                resole(false);
              } else {
                this.editLockNum.set(row.id, {
                  funID,
                  key,
                  rowID: row.id,
                  cmd
                });
                cmd === 'lock'
                  ? Tsrv.TlockInfo.add({
                      funID,
                      rowID: row.id,
                      key
                    })
                  : Tsrv.TlockInfo.removeLockInfoByFunID(funID);
                resole(true);
              }
              if (cmd === 'unLock') {
                this.editLockNum.delete(row.id);
              }
            })
            .catch(err => {
              resole(false);
              console.error(err);
            });
        }
      }
    });
  }

  public unLockALL() {
    this.editLockNum.forEach(el => {
      const _el = Tsrv.utils.clone(el);
      _el.cmd = 'unLock';
      this.apiEditLock(_el)
        .then(([res, err]) => {
          // console.error(err ?? res.msg);
          this.editLockNum.delete(el.rowID);
        })
        .catch(err => {
          console.error(err);
        });
    });

    this.oBasePanel.isLoadEditLock = false;
  }

  public apiEditLock(p: {
    funID: string;
    cmd: 'lock' | 'unLock';
    rowID: string;
    key: string;
  }): Promise<[ifs.I_setDataRes, string]> {
    return Tsrv.standardPostReq<ifs.I_setDataRes, any>(p, Tsrv.url.editLock);
  }

  public loadEditLock(): Promise<boolean> {
    const oBasePanel = this.oBasePanel;
    this.editLocked.clear();
    oBasePanel.isLoadEditLock = false;
    return new Promise((resolve, reject) => {
      // 正在加载
      oBasePanel.loading = true;
      const gpd = new ts.T_getPartDataArg();
      gpd
        .setFunName(Tsrv.globalVar.funName.EDIT_LOCK)
        .setLang(oBasePanel.$i18n.locale || 'en-US');
      gpd.setDbType(Tsrv.globalVar.dbType.MYSQL);
      gpd.setPage(1, 99999);
      let funID = ``;
      if (this.oBasePanel.config.status === 'main') {
        funID = Tsrv.getMinFunID(this.oBasePanel.config.mainFun);
      } else {
        funID = Tsrv.getDeputyFunID(
          this.oBasePanel.config.mainFun,
          this.oBasePanel.config.name
        );
      }
      gpd.setFilter({
        $and: [
          { [Tsrv.globalVar.fieldName.funID]: { $eq: funID } },
          { end_time: { $gt: new Date().toLocaleString() } }
        ]
      });
      Tsrv.getData<any, ifs.I_getPartDataArg>(gpd)
        .then(([b, res, rows, msg]) => {
          oBasePanel.loading = false;
          if (!b) {
            msg && oBasePanel.$msg(msg);
            resolve(false);
          }
          // 如果行数 > 0 则设置第一行选中
          if (res.data.total > 0) {
            rows.forEach(el => {
              if (el['f_code']) {
                this.editLocked.add(el['f_code']);
              }
            });
          }
          resolve(true);
        })
        .catch(e => {
          // 正在加载
          oBasePanel.loading = false;
          console.error(e);
        });
    });
  }

  // 获取功能配置
  public getCompConfig() {
    return this.oBasePanel.config;
  }

  // 会话消息处理
  public interactionMsgHandle(
    msg: N_oInteraction.I_msg,
    resData: any = null,
    serviceData?: any
  ) {
    if (Tsrv.utils.noValue(msg)) {
      return;
    }
    const obj = new ts.T_interaction();
    const res = obj.parseMsg(msg);
    if (res.isErr()) {
      this.oBasePanel.$msg(res.errmsg);
    } else {
      const interactionCf = res.getReturnData('conf');
      switch (interactionCf.cmd) {
        case N_oInteraction.V_cmd.FIELD_EVENT:
          // eslint-disable-next-line no-case-declarations
          const { fieldData } = serviceData;
          this.handleFieldEvent(interactionCf, fieldData).then(r => {
            if (r) {
              this.interactionEventHandle({}, msg?.next);
            }
          });
          break;
        case N_oInteraction.V_cmd.JUMP_TO_FUN:
          this.handleJumpToFun(interactionCf).then(r => {
            if (r) {
              this.interactionEventHandle({}, msg?.next);
            }
          });
          break;
        case N_oInteraction.V_cmd.EXECUTE_ACTIONS: // 执行组件动作
          this.handleFrontendActions(interactionCf).then(r => {
            if (r) {
              this.interactionEventHandle({}, msg?.next);
            }
          });
          break;
        // 统一替换为 “前端行为”
        case N_oInteraction.V_cmd.FRONTEND_BEHAVIOR:
          this.interactiveBehavior(interactionCf).then(resp => {
            if (resp) {
              this.interactionEventHandle(msg?.next);
            }
          });
          break;
        default:
          Tsrv.utils
            .createModal('oInteraction', interactionCf)
            .then(r => {
              this.interactionEventHandle({ resp: r }, msg.next);
            })
            .catch(e => {
              console.error(e);
              this.oBasePanel.$msg(e);
            });
          break;
      }
    }
  }

  public doEvent(action: string, params: any, serviceData?: any) {
    return new Promise<boolean>((resove, reject) => {
      Tsrv.doEvent(
        action,
        Tsrv.getFunInfo(this.oBasePanel.funName.formName) as ifs.I_funInfo,
        () => params
      )
        .then(r => {
          const res = r.getReturnData('conf');
          if (r.isErr()) {
            this.oBasePanel.$msg(r.errmsg);
          }
          if (Tsrv.utils.noValue(res)) {
            resove(false);
            return;
          }
          if (res.res?.data?.openUrl && res.res.success) {
            Tsrv.reliablySendingBusEvent(
              'OPEN_URL',
              undefined,
              undefined,
              undefined,
              res.res.data.openUrl
            );
          }
          // 0 存储过程  1 系统策略 2 规则库 3 web请求
          if (res.apiType <= 2) {
            this.oBasePanel.$msg(res.res.msg);
            // 会话处理
            this.interactionMsgHandle(
              res.res.data?.request,
              res.res.data?.data,
              serviceData
            );
            // this.oBasePanel.loadData();
            // this.oBasePanel.$emit('loadFormData', res.res.data.data);
          } else if (res.apiType === 3) {
            // 请求接口
            const p = {
              funName: this.oBasePanel.funName.formName,
              from: 'WebRequest',
              title: action,
              data: {
                req: res['data'],
                res: res.res[0].data
              },
              // data: res.res[0].data.data,
              parentID: 0
            };
            this.doEvent(Tsrv.lexicon.globalVar.spName.webApiReq, p);
          }
          resove(true);
        })
        .catch(err => {
          console.error(err);
          reject(false);
        });
    });
  }

  interactionEventHandle(params: any, next: any = null) {
    // if (Object.prototype.hasOwnProperty.call(params, 'resp')) {
    //   if (Tsrv.utils.noValue(params?.resp?.data))
    //     params.resp.data = this.getSelectedData('select');
    // } else {
    //   params = this.getSelectedData('select');
    //   params.from = 'nextSp';
    //   delete params.title;
    // }
    if (
      !Tsrv.utils.noValue(next) &&
      ((next?.ok && next?.ok?.spName) || (next?.cancel && next?.cancel?.spName))
    ) {
      if (next?.ok && next?.ok?.spName) {
        this.handleInteractionParams(next.ok?.spParams, params);
        if (Object.prototype.hasOwnProperty.call(params, 'resp')) {
          if (params?.resp?.action && params?.resp?.action === 'confirm')
            // this.doEvent(next.ok.spName, next.ok?.spParams ?? params);
            this.doEvent(next.ok.spName, params);
        } else {
          // this.doEvent(next.ok.spName, next.ok?.spParams ?? params);
          this.doEvent(next.ok.spName, params);
        }
      } else if (
        next?.cancel &&
        next?.cancel?.spName &&
        params?.resp?.action &&
        params?.resp?.action === 'cancel'
      ) {
        this.handleInteractionParams(next.cancel?.spParams, params);
        // this.doEvent(next.ok.spName, next.cancel?.spParams ?? params);
        this.doEvent(next.ok.spName, params);
      }
      if (next?.ok && next?.ok?.actions) {
        if (Object.prototype.hasOwnProperty.call(params, 'resp')) {
          if (params?.resp?.action && params?.resp?.action === 'confirm')
            this.handleInteractiveBehaviors(next.ok.actions, next.ok);
        } else {
          this.handleInteractiveBehaviors(next.ok.actions, next.ok);
        }
      } else if (
        next?.cancel &&
        next?.cancel?.actions &&
        params?.resp?.action &&
        params?.resp?.action === 'cancel'
      ) {
        this.handleInteractiveBehaviors(next.cancel.actions, next.cancel);
      }
    } else {
      // this.doEvent('_sys_interaction_default_resp', params);
    }
  }

  private handleFrontendActions(res) {
    return new Promise((resolve, reject) => {
      const actions = Tsrv.utils.clone(res.actions);
      this.handleInteractiveBehaviors(actions);
      // this.interactionEventHandle({}, res?.next);
      // // this.defaultIteractiveEventHandle(next);
      resolve(true);
    });
  }

  // 处理交互消息 确认/取消 后动作
  private handleInteractiveBehaviors(actions: object, tableName?: string) {
    return new Promise((resolve, reject) => {
      Object.keys(actions).forEach(key => {
        switch (key) {
          case 'isRefresh':
            this.oBasePanel.commitEvent('reload');
            resolve(true);
            break;
          case 'isEdit':
            this.oBasePanel.commitEvent('edit', actions[key]);
            resolve(true);
            break;
          case 'editable':
            this.oBasePanel.commitEvent('edit', actions[key]);
            resolve(true);
            break;
          case 'download':
            this.downloadEvent(actions[key]);
            resolve(true);
            break;
          case 'crossSystem':
            this.handleCrossSystem(actions[key]);
            resolve(true);
            break;
          case 'setCustomBtnStatus':
            if (
              actions['setCustomBtnStatus'] &&
              !Tsrv.utils.noValue(actions['setCustomBtnStatus'])
            ) {
              const addon = this.oBasePanel.toolbar['addon'];
              const customBtnStatus = actions['setCustomBtnStatus'].filter(
                el => {
                  return addon.some(el2 => el2.title === el.title);
                }
              );
              customBtnStatus.forEach(el => {
                if (Object.prototype.hasOwnProperty.call(el, 'status'))
                  // this.setCustBtnEnalbed(el.title, el.status)
                  this.setCustBtnStatus(el.title, el.status);
              });
            }
            resolve(true);
            break;
          case 'events':
            if (
              !Tsrv.noValue(actions['events']) &&
              Array.isArray(actions['events'])
            ) {
              const events = actions['events'];
              events.forEach(event => {
                if (Tsrv.utils.isJSONString(event.params)) {
                  event.params = JSON.parse(event.params);
                }
                Tsrv.reliablySendingBusEvent(
                  event.name,
                  this.oBasePanel.$bus,
                  10,
                  100,
                  event.params
                );
              });
            }
            resolve(true);
            break;
          case 'styleRules':
            if (
              !Tsrv.noValue(actions['styleRules']) &&
              Array.isArray(actions['styleRules'])
            ) {
              this.setStyleRule(actions['styleRules']);
            }
            resolve(true);
            break;
          // 字段设置（1：指定值临时改变、禁止编辑。2：添加basegrid的rule）
          case 'fieldSettings':
            this.handleFieldSettings(actions[key], tableName)
              .then(res => {
                if (res) {
                  resolve(true);
                }
              })
              .catch(() => {});
            break;
          default:
            break;
        }
      });
    });
  }

  /**
   * @description: "cmd": "frontendBehavior"的 处理交互行为函数
   * @param {any} msg : 事件返回参数
   * @return {*}
   * @author: swc
   * @Date: 2025-01-18 09:17:51
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private interactiveBehavior(msg: any): Promise<any> {
    return new Promise((resolve, reject) => {
      const msgContent = Tsrv.utils.clone(msg);
      const frontendBehavior = msgContent['frontendBehavior'];
      const funName = this.oBasePanel.name;
      const tableName = [funName.formName, ...funName.tableNames];
      if (!Tsrv.noValue(frontendBehavior)) {
        const haviorPs = Object.keys(frontendBehavior);
        if (
          haviorPs.indexOf('funConfs') > -1 ||
          haviorPs.indexOf('action') > -1
        ) {
          let behaviors = {};
          const action = frontendBehavior['action'];
          const funConfs = frontendBehavior['funConfs'];
          if (!Tsrv.noValue(funConfs)) {
            // behaviors = { ...behaviors, ...funConfs };
            behaviors = Object.assign(behaviors, funConfs);
          }
          if (!Tsrv.noValue(action)) {
            behaviors = Object.assign(behaviors, { action });
          }
          Object.keys(behaviors).forEach(key => {
            if (tableName.indexOf(key) > -1 || key === 'action') {
              const bs = behaviors[key];
              this.handleInteractiveBehaviors(
                bs,
                key === 'action' ? undefined : key
              ).then(res => {
                if (res) {
                  resolve(true);
                } else {
                  resolve(false);
                }
              });
            }
          });
        }
      } else {
        console.error('msgContent is null');
        resolve(false);
      }
    });
  }

  private handleInteractionParams(settingP: any = null, defalutP: any = null) {
    // 交互next 传参。如果json中返回的没有 spParams
    if (Tsrv.utils.noValue(settingP)) {
      if (Object.prototype.hasOwnProperty.call(defalutP, 'resp')) {
        if (Tsrv.utils.noValue(defalutP?.resp?.data))
          defalutP.resp.data = this.getSelectedData();
      } else {
        // defalutP = this.getSelectedData();
        // defalutP.from = 'nextSp';
        // delete defalutP.title;
        defalutP['funName'] = this.oBasePanel.funName.formName;
        defalutP['data'] = {
          rows: {}
        };
        defalutP.from = 'nextSp';
        defalutP.data[this.oBasePanel.name.formName] = this.oBasePanel.formID;

        this.oBasePanel.name.tableNames.forEach((name, idx) => {
          const rows = this.getTableInstance(idx)
            .grid.getCheckboxRecords()
            .filter(el => {
              return !!el.id;
            });
          defalutP.data[name] = rows.map(el => el.id);
          defalutP.data.rows[name] = rows;
        });

        defalutP.data['custBtns'] = [];
        this.oBasePanel.toolbar['addon'].forEach(el => {
          defalutP.data['custBtns'].push({ title: el.title, status: el.auth });
        });
      }
      // return defalutP;
    } else {
      // 有 spParams 的处理
      if (Object.prototype.hasOwnProperty.call(defalutP, 'resp')) {
        settingP.forEach((el: any, idx: number) => {
          if (el?.key) {
            // if (el.originType === 'dynamic') { // 动态值:dynamic，静态值:static
            if (el.key.indexOf('$') > -1) {
              // 动态值:dynamic，静态值:static
              this.getSpParamsByDynamic(
                el.value,
                defalutP.resp.data,
                el.key.split('$')[1] ?? `key${idx}`
              );
            } else {
              defalutP.resp.data[el.key ?? `key${idx}`] = el.value;
            }
          }
        });
        // for (let index = 0; index < array.length; index++) {
        //   const element = array[index];

        // }
        // return defalutP;
      } else {
        // defalutP = this.getSelectedData();
        defalutP['funName'] = this.oBasePanel.funName.formName;
        defalutP['data'] = {
          rows: {}
        };
        defalutP.from = 'nextSp';
        defalutP.data[this.oBasePanel.name.formName] = this.oBasePanel.formID;

        this.oBasePanel.name.tableNames.forEach((name, idx) => {
          const rows = this.getTableInstance(idx)
            .grid.getCheckboxRecords()
            .filter(el => {
              return !!el.id;
            });
          defalutP.data[name] = rows.map(el => el.id);
          defalutP.data.rows[name] = rows;
        });

        defalutP.data['custBtns'] = [];
        this.oBasePanel.toolbar['addon'].forEach(el => {
          defalutP.data['custBtns'].push({ title: el.title, status: el.auth });
        });
        settingP.forEach((ell: any, iidx: number) => {
          if (ell?.key) {
            // if (ell.originType === 'dynamic') { // 动态值:dynamic，静态值:static
            if (ell.key.indexOf('$') > -1) {
              // 动态值:dynamic，静态值:static
              this.getSpParamsByDynamic(
                ell.value,
                defalutP.resp.data,
                ell.key.split('$')[1] ?? `key${iidx}`
              );
            } else {
              defalutP.data[ell.key ?? `key${iidx}`] = ell.value;
            }
          }
        });
        // return defalutP;
      }
    }
  }

  private getSpParamsByDynamic(re: any, o: object, k: string) {
    if (Tsrv.utils.isJSONString(re)) {
      re = JSON.parse(re);
    }
    switch (re.cmd) {
      case 'getAutoNum':
        this.getAutoNum(re.params, o, k);
        break;
      default:
        break;
    }
  }

  private async getAutoNum(re: any, o: object, k: string) {
    // const [resp, err] = await Tsrv.getAutoNum('test1_reftable', 'f_code')
    const [resp, err] = await Tsrv.getAutoNum(re.funName, re.field);
    if (err) {
      this.oBasePanel.$msg(err);
      o[k] = '';
    } else {
      o[k] = resp?.data?.code;
    }

    // Promise.all().then(result => {

    // });
  }

  public getRegEventName(type: 'send' | 'receive', eventName: string): string {
    for (const itm of this.oBasePanel.regCustEventName as Array<
      N_oBaseGrid.I_regCustEventName
    >) {
      if (type === 'receive' && itm?.receive) {
        if (itm.receive.source === eventName) {
          return itm.receive.target;
        }
      }
      if (type === 'send' && itm?.send) {
        if (itm.send.source === eventName) {
          return itm.send.target;
        }
      }
    }
    return undefined;
  }

  // 处理字段事件
  private handleFieldEvent(res: any, fieldInfo: any) {
    return new Promise((resove, reject) => {
      const detail = fieldInfo.data;
      const updFields = res['updFields'];
      const fieldsStatus = res['fieldsStatus'];
      if (fieldInfo.fromComponent === 'table') {
        // 更新字段
        if (!Tsrv.utils.noValue(updFields)) {
          const fullData = detail.$table.getTableData().fullData;
          Object.keys(updFields).forEach(key => {
            if (key.indexOf('.') > -1) {
              const field = key.split('.')[1];
              for (let i = 0; i < fullData.length; i++) {
                if (fullData[i]._XID === detail.row._XID) {
                  fullData[i][field] = updFields[key];
                  detail.$table.updateData();
                  break;
                }
              }
            }
          });
        }

        // 字段的禁用状态
        if (!Tsrv.utils.noValue(fieldsStatus)) {
          Object.keys(fieldsStatus).forEach(item => {
            if (item.indexOf('.') > -1) {
              const field = item.split('.')[1];
              const targetField = Tsrv.utils.find(
                fieldInfo.comp.tableColumns,
                // it => it.field === field
                it => it.title === field
              );
              if (!Tsrv.utils.noValue(targetField.editRender.props)) {
                targetField.editRender.props.disabled = fieldsStatus[item];
              }
            }
          });
        }
      } else if (fieldInfo.fromComponent === 'form') {
        if (!Tsrv.utils.noValue(updFields)) {
          Object.keys(updFields).forEach(key => {
            if (key.indexOf('.') > -1) {
              const field = key.split('.')[1];
              fieldInfo.comp.setFieldValue(field, updFields[key]);
              fieldInfo.data.$form.data[field] = updFields[key];
            }
          });
        }

        // 字段的禁用状态
        if (!Tsrv.utils.noValue(fieldsStatus)) {
          Object.keys(fieldsStatus).forEach(item => {
            if (item.indexOf('.') > -1) {
              const field = item.split('.')[1];
              const targetField = Tsrv.utils.find(
                fieldInfo.comp.formColumns,
                // it => it.field === field
                it => it.title === field
              );
              if (!Tsrv.utils.noValue(targetField.itemRender.props)) {
                targetField.itemRender.props.disabled = fieldsStatus[item];
              }
            }
          });
        }
      }
      resove(true);
    });
  }

  /**
   * @description 处理字段事件
   * @param resp 响应数据
   * @param funName 操作表名
   * @returns
   */
  private handleFieldSettings(resp: any, tableName: string) {
    return new Promise((resove, reject) => {
      const oBasePanel = this.oBasePanel;
      if (Tsrv.noValue(tableName)) {
        oBasePanel.$msg(Tsrv.getI18nByValue('缺少功能名'));
        return;
      }
      const cell = resp['cell'];
      if (!Tsrv.noValue(cell)) {
        // 字段事件—— 修改 setting 的逻辑
        const setting = cell['setting'];
        if (!Tsrv.noValue(setting) && !Tsrv.noValue(setting['options'])) {
          const options = setting['options'];
          // 要修改的 项
          if (!Tsrv.noValue(options) && Array.isArray(options)) {
            if (oBasePanel.name.formName === tableName) {
              // 是表格baseform-表头时
            } else if (oBasePanel.name.tableNames.indexOf(tableName) > -1) {
              // 是表格basegrid-表体时
              oBasePanel.name.tableNames.forEach((name, idx) => {
                if (name === tableName) {
                  const tableInstance = this.getTableInstance(idx);
                  const fullData = tableInstance.GT_editor.getGrid().getTableData()
                    .fullData;
                  for (let k = 0; k < options.length; k++) {
                    const option = options[k];
                    if (Tsrv.noValue(option['id'])) {
                      continue;
                    }
                    // 更新字段
                    if (
                      !Tsrv.noValue(option['setValue']) &&
                      Array.isArray(option['setValue'])
                    ) {
                      option['setValue'].forEach(field => {
                        for (let i = 0; i < fullData.length; i++) {
                          if (fullData[i].id === option.id) {
                            fullData[i][field['key']] = field['value'];
                            break;
                          }
                        }
                      });
                    }
                    // 字段禁用状态 （后续改为样式）
                    if (
                      !Tsrv.noValue(option['setStyle']) &&
                      Array.isArray(option['setStyle'])
                    ) {
                      /* 注：现在实现方案是：利用vxetable的rules功能，
                          ——未来需要优化改为：修改表格的指定input的样式效果
                        （实现方案：this.oBasegrid.tableColumns中的editRender.prop
                        （在当前input中可获得row数据，根据row数据id来判断是否使用该样式效果））
                        */
                      option['setStyle'].forEach(field => {
                        // 设置 rules 方式实现
                        const cellEditCfg = tableInstance.cellEditCfg;
                        const findField = cellEditCfg.find(
                          it => it.field === field['key']
                        );
                        if (Tsrv.noValue(findField)) {
                          cellEditCfg.push({
                            field: field['key'],
                            editable: !field['value']?.isDisable,
                            conditions: {
                              field: 'id',
                              operator: 'has',
                              type: 'text',
                              value: option.id
                            }
                          });
                        }
                      });
                    }
                  }
                }
              });
            }
          }
        }
        // 字段事件—— 修改 rules 的逻辑 （仅对表格-base-grid生效）
        if (oBasePanel.name.tableNames.indexOf(tableName) > -1) {
          const rules = cell['rules'];
          if (!Tsrv.noValue(rules) && Array.isArray(rules)) {
            oBasePanel.name.tableNames.forEach((name, idx) => {
              if (name === tableName) {
                const tableInstance = this.getTableInstance(idx);
                rules.forEach(rule => {
                  tableInstance.addVxegridRules('cell', rule);
                });
              }
            });
          }
        }
      }
      // 行事件、列事件 的 修改 rules 的逻辑 仅限于 表格-base-grid
      if (oBasePanel.name.tableNames.indexOf(tableName) > -1) {
        const tableInstance = this.getTableInstance(
          oBasePanel.name.tableNames.indexOf(tableName)
        );
        if (!Tsrv.noValue(tableInstance)) {
          // 行事件—— 修改 rules 的逻辑
          const row = resp['row'];
          if (!Tsrv.noValue(row)) {
            const rules = row['rules'];
            if (!Tsrv.noValue(rules) && Array.isArray(rules)) {
              rules.forEach(rule => {
                tableInstance.addVxegridRules('row', rule);
              });
            }
          }
          // 列事件—— 修改 rules 的逻辑
          const column = resp['column'];
          if (!Tsrv.noValue(column)) {
            const rules = column['rules'];
            const fieldFilter = column['fieldFilter'];
            if (!Tsrv.noValue(rules) && Array.isArray(rules)) {
              rules.forEach(rule => {
                tableInstance.addVxegridRules('column', rule);
              });
            }
            if (!Tsrv.noValue(fieldFilter)) {
              tableInstance.setFieldFilter(fieldFilter);
            }
          }
        }
      }
    });
  }

  // 跳转指定功能（单据）
  public handleJumpToFun(p: any) {
    return new Promise((resove, reject) => {
      const oBasePanel = this.oBasePanel;
      oBasePanel.$store
        .dispatch('getLayoutConfigAsync', {
          funid: null,
          field: p.funName,
          type: 'component'
        })
        .then((res: any) => {
          const funType = res?.current?.name;
          if (!Tsrv.noValue(funType)) {
            oBasePanel.addTabFunc(p.funName).then((resp: any) => {
              resove(resp);
              if (funType.toLowerCase() === 'basepanel') {
                // 如果有handleSearchTo函数 （可修改：判断是否为单据类型的功能）
                const that = resp.$children[0].$children[0];
                if (
                  that &&
                  typeof that?.handleSearchTo === 'function' &&
                  Tsrv.utils.isNumber(p.pageNo)
                ) {
                  const timeout = p.pageNo === 0 ? 800 : 0;
                  setTimeout(() => {
                    // 后续操作
                    if (p.pageNo === 0) {
                      that.commitEvent('insert_actived');
                    } else {
                      that.handleSearchTo(p.pageNo).then(r => {
                        if (r && !Tsrv.utils.noValue(p?.actions)) {
                          that.GT_command.handleInteractiveBehaviors(p.actions);
                        }
                      });
                    }
                  }, timeout);
                }
              }
            });
          }
        });
    });
  }

  // 事件交互—— 跨系统交互
  public handleCrossSystem(p: any) {
    const mode = p?.mode ?? 'tab';
    const url = p?.url ?? '';
    if (Tsrv.noValue(url)) {
      return;
    }
    switch (mode) {
      case 'tab':
        window.open(url);
        break;
      case 'popup':
        Tsrv.utils
          .createModal('o-iframe', {
            modalSize: [p?.width ?? 560, p?.height ?? 420],
            modalTitle: p.title ?? Tsrv.getI18nByValue('外部系统'),
            config: {
              url
            }
          })
          .then(res => {});
        break;
      default:
        break;
    }
  }

  // 获取活跃数据（即选中的数据--表头id，表体选中的id）
  public getSelectedData() {
    const params = {
      funName: this.oBasePanel.funName.formName,
      title: '',
      from: '',
      data: {
        rows: {}
      }
    };
    params.data[this.oBasePanel.name.formName] = this.oBasePanel.formID;
    params.data.rows[this.oBasePanel.name.formName] = [
      this.oBasePanel.getFormData()
    ];

    this.oBasePanel.name.tableNames.forEach((name, idx) => {
      const rows = this.getTableInstance(idx)
        .grid.getCheckboxRecords()
        .filter(el => {
          return !!el.id;
        });
      params.data[name] = rows.map(el => el.id);
      params.data.rows[name] = rows;
    });

    params.data['custBtns'] = [];
    this.oBasePanel.toolbar['addon'].forEach(el => {
      params.data['custBtns'].push({ title: el.title, status: el.auth });
    });

    return params;
  }

  public setCustBtnEnalbed(btnTitle: string, s: boolean) {
    const a = this.oBasePanel.customPermission.data[btnTitle] ?? 1;
    if (a === 1) {
      this.oBasePanel.toolbar['addon'].forEach(el => {
        if (el.title === btnTitle) {
          el.auth = s;
        }
      });
    }
  }

  // 获取表格的自定义按钮状态
  public getCustBtnStatus() {
    const gpd = new ts.T_getPartDataArg();
    const filter = {
      fun_name: this.oBasePanel.funName.formName
    };
    gpd.setFilter(filter);
    gpd.setFunName(Tsrv.globalVar.funName.SYS_CUSTOMBTN_STATUS);
    gpd.setTableName(Tsrv.globalVar.funName.SYS_CUSTOMBTN_STATUS);
    gpd.setDbType(Tsrv.globalVar.dbType.MYSQL);
    gpd.setLang(this.oBasePanel.$i18n.locale);
    gpd.setPage(1, 99999);
    gpd.setRule({} as ifs.I_rule);
    Tsrv.getData(gpd).then(([b, res, rows, err]) => {
      if (!b && err) {
        console.error(err ?? res.msg);
      } else {
        const customBtns = [];
        if (!Tsrv.utils.noValue(rows)) {
          rows.forEach(el => {
            customBtns.push({
              title: el.button_name,
              status: !el.disabled,
              id: el.id
            });
          });
        }
        this.oBasePanel.customBtnStatus = customBtns;
        if (this.oBasePanel.toolbar['addon'].length > 0)
          this.oBasePanel.toolbar['addon'].forEach(el => {
            // el.auth = !!data[el.title];
            const btn = customBtns.find(el2 => el2.title === el.title);
            if (el?.readCurrentStatus === true && !Tsrv.utils.noValue(btn)) {
              this.setCustBtnEnalbed(el.title, btn.status);
            }
          });
      }
    });
  }

  // 设置表格的自定义按钮状态
  public setCustBtnStatus(title: string, status: boolean) {
    const btn = this.oBasePanel.toolbar['addon'].find(el => el.title === title);
    if (btn?.readCurrentStatus) {
      const ctd = new ts.T_ctdArg();
      ctd
        .setTableName(Tsrv.globalVar.funName.SYS_CUSTOMBTN_STATUS)
        .setDbType(Tsrv.globalVar.dbType.MYSQL)
        .setRule({} as ifs.I_rule);
      // 如果该表格自定义按钮记录中没有此按钮则向表中新增
      const btnStatus = this.oBasePanel.customBtnStatus.find(
        el2 => el2.title === title
      );
      if (Tsrv.utils.noValue(btnStatus)) {
        const scope = {};
        const insertRecord = [
          { field: 'id', value: Tsrv.getSnowIDFmtStr() },
          { field: 'fun_name', value: this.oBasePanel.funName.formName },
          { field: 'button_name', value: title },
          { field: 'disabled', value: status ? 0 : 1 }
        ];
        // if (this.scope && this.scope?.field) {
        //   scope = { [`${this.scope.field}`]: this.scope.value };
        // }
        const bDatas: ifs.I_baseData[] = [];
        const bData = new ts.T_baseData();
        bData
          .setDataRule({} as ifs.I_rule)
          .setFileInfo({})
          .setRowData(...(insertRecord as ifs.I_fv[]));
        bDatas.push(bData);
        ctd.setInsRecDataMany(scope, ...bDatas);
      } else {
        //  如果该表格自定义按钮记录中有此按钮则修改
        const updateRecord = [{ field: 'disabled', value: status ? 0 : 1 }];
        const filter = { id: btnStatus.id };
        const ctdUpdDatas: ifs.I_ctdUpdData[] = [];
        const ctdUpdData = new ts.T_ctdUpdData();
        ctdUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
        // filter = { id: btnStatus.id };
        ctdUpdData.setFilter(filter);
        ctdUpdData.setRowData(...(updateRecord as ifs.I_fv[]));
        ctdUpdDatas.push(ctdUpdData);
        ctd.setUpdRecDataMany(...ctdUpdDatas);
      }
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        msg && this.oBasePanel.$msg(msg);
        if (b) {
          // resolve(true);
          this.setCustBtnEnalbed(title, status);
        } else {
          // reject();
        }
      });
    } else {
      this.setCustBtnEnalbed(title, status);
    }
  }

  private handleEditorStateChange(editorState: EDIT_STATE) {
    let isEditable = false;
    if (editorState === EDIT_STATE.MODIFY || editorState === EDIT_STATE.NEW) {
      isEditable = true;
    }
    this.setCustBtnStatusByEditStatus(isEditable);
  }

  public setCustBtnStatusByEditStatus(status: boolean) {
    const addon = this.oBasePanel.config.toolbar.addon;
    if (Array.isArray(addon) === false) {
      return;
    }
    addon.forEach(ele => {
      if (ele?.editedEnabled === true) {
        this.handleCustBtnStatus(ele.title, 'auth', status);
      }
      if (ele?.editedShow === true) {
        this.handleCustBtnStatus(ele.title, 'isShow', status);
      }
    });
  }

  public handleCustBtnStatus(btnTitle: string, status: string, value: boolean) {
    if (Tsrv.noValue(this.oBasePanel.customPermission)) {
      return;
    }
    const a = this.oBasePanel.customPermission.data[btnTitle] ?? 1;
    if (a === 1) {
      this.oBasePanel.toolbar['addon'].forEach(el => {
        if (el.title === btnTitle) {
          el[status] = value;
        }
      });
    }
  }

  // 单据中的表格行内样式
  public setStyleRule(styleRules: Array<any>) {
    this.oBasePanel.name.tableNames.forEach((name, index) => {
      const styleRule = styleRules.find(r => r.funName === name);
      if (!Tsrv.noValue(styleRule?.styleRule)) {
        this.getTableInstance(index).setRules(styleRule.styleRule);
      }
    });
  }

  // 下载
  public downloadEvent(info: any) {
    if (!Tsrv.noValue(info)) {
      const oBasePanel = this.oBasePanel;
      const fName = info?.fileName || null;
      const fPath = info?.path || null;
      const fileInfo = info?.fileInfo ?? null;
      const downloadFiles = [];
      // 1、通过文件信息来下载 fileName path
      if (!Tsrv.noValue(fName) && !Tsrv.noValue(fPath)) {
        const file = {
          fName,
          fPath,
          fileName: fName
        };
        downloadFiles.push(file);
      }
      // 2、通过表格数据来下载
      if (!Tsrv.noValue(fileInfo)) {
        const field = fileInfo.field;
        const row = this.oBasePanel.getFormData();
        if (Tsrv.noValue(row)) {
          oBasePanel.$msg(Tsrv.getI18nByValue('未找到该数据'));
          return;
        }
        let value = row[field];
        if (Tsrv.utils.isJSONString(value)) {
          value = JSON.parse(value);
        }
        const files = value?.files;
        if (!Tsrv.noValue(files) && Array.isArray(files)) {
          for (let i = 0; i < files.length; i++) {
            const el = files[i];
            if (
              Tsrv.noValue(el?.libFileName) ||
              Tsrv.noValue(el?._content_) ||
              Tsrv.noValue(el?.fileName)
            ) {
              continue;
            }
            const file = {
              fName: el.libFileName,
              fPath: el._content_,
              fileName: el.fileName
            };
            downloadFiles.push(file);
          }
        }
      }
      if (downloadFiles.length === 0) return;
      downloadFiles.forEach(item => {
        const dwn = new ts.T_downloadArg();
        dwn.setFileName(item.fName).setPath(item.fPath);
        Tsrv.download(dwn, true, item.fileName)
          .then(r => {
            if (r.err) {
              oBasePanel.$msg(r.err);
            }
          })
          .catch(err => {
            oBasePanel.$msg(err);
          });
      });
    }
  }

  // // 处理组件协调
  // public receEventCoordination(
  //   m: N_oSetupPanel.N_comps.I_eventCoordinationMsg
  // ) {
  //   switch (m.action.toolbar) {
  //     case 'insert':
  //       this.setTempToolbarStatusDisabled();
  //       break;
  //     case 'delete':
  //       break;
  //     case 'unAudit':
  //       break;
  //     case 'edit':
  //       this.setTempToolbarStatusDisabled();
  //       break;
  //     case 'unEdit':
  //       this.setTempToolbarStatusUnDisabled();
  //       break;
  //     case 'save':
  //       this.setTempToolbarStatusUnDisabled();
  //       break;
  //     case 'audit':
  //       break;
  //     case 'refresh':
  //       this.setTempToolbarStatusUnDisabled();
  //       break;
  //     default:
  //       throw new Error(`无法识别的事件属性[${m.action.toolbar}]`);
  //   }
  // }

  // private setTempToolbarStatusDisabled() {
  //   this.toolbarStatusBak = Tsrv.utils.clone(this.oBasePanel.toolbar, true);
  //   this.oBasePanel.toolbar.previous.isDisable = true;
  //   this.oBasePanel.toolbar.jumpFirst.isDisable = true;
  //   this.oBasePanel.toolbar.next.isDisable = true;
  //   this.oBasePanel.toolbar.jumpLast.isDisable = true;
  //   this.oBasePanel.toolbar.save.isDisable = true;
  //   this.oBasePanel.toolbar.edit.isDisable = true;
  //   this.oBasePanel.toolbar.audit.isDisable = true;
  //   this.oBasePanel.toolbar.delete.isDisable = true;
  //   this.oBasePanel.toolbar.insert.isDisable = true;
  //   this.oBasePanel.toolbar.edit.isDisable = true;
  //   this.oBasePanel.toolbar.refresh.isDisable = true;
  //   this.setToolbarStatus('selbill', 'isDisable', true);
  //   this.oBasePanel.toolbar.audit.isDisable = true;
  // }

  // private setTempToolbarStatusUnDisabled() {
  //   if (this.toolbarStatusBak) {
  //     this.oBasePanel.toolbar = this.toolbarStatusBak;
  //     this.toolbarStatusBak = null;
  //   }
  // }

  // // 处理组件协调
  // public sendEventCoordination(
  //   type: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  // ) {
  //   const messageConf = this.oBasePanel.config?.messageConfig;
  //   if (!messageConf) {
  //     throw new Error(`找不到事件相关设置`);
  //   }
  //   if (!messageConf?.eventGroup) {
  //     return;
  //   }
  //   const m: N_oSetupPanel.N_comps.I_eventCoordinationMsg = {
  //     type: 'coordination',
  //     fromComp: {
  //       funName: this.oBasePanel.funName.formName,
  //       fromEvenID: messageConf.custDefListener.coordination
  //     },
  //     action: {
  //       toolbar: type
  //     }
  //   };
  //   Object.keys(messageConf.eventGroup).forEach(k => {
  //     const toID: string =
  //       messageConf.eventGroup[k].custDefListener.coordination;
  //     if (
  //       this.oBasePanel.config.messageConfig.custDefListener.coordination !==
  //       toID
  //     ) {
  //       Tsrv.reliablySendingBusEvent(this.oBasePanel.$bus, null, null, toID, m);
  //     }
  //   });
  // }

  // 构建组件协作处理类
  public newTcompCoordination(conf: any) {
    // 组件调度
    this.TCoordination = new ts.T_compCoordination(
      conf.name,
      conf.messageConfig,
      {
        setTempToolbarStatusDisabled: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          this.setTempToolbarStatusDisabled(p);
        },
        setTempToolbarStatusUnDisabled: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          this.setTempToolbarStatusUnDisabled(p);
        },
        cleanSubCompData: (
          p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
        ) => {
          this.oBasePanel.cleanSubCompData(p);
        },
        setMask: (p: boolean) => {
          this.oBasePanel.isMask = p;
        }
      }
    );
  }

  // 处理组件协调
  public receEventCoordination(
    m: N_oSetupPanel.N_comps.I_eventCoordinationMsg
  ) {
    this.TCoordination.receEventCoordination(m)
      .then(([b, msg]) => {})
      .catch(msg => {
        console.error(msg);
        // this.oBasePanel.$msg(msg);
      });
  }

  private setTempToolbarStatusDisabled(
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    // if (Tsrv.utils.noValue(this.toolbarStatusBak)) {
    //   this.toolbarStatusBak = Tsrv.utils.clone(this.oBaseGrid.toolbar, true);
    //   this.oBaseGrid.toolbar.previous.isDisable = true;
    //   this.oBaseGrid.toolbar.jumpFirst.isDisable = true;
    //   this.oBaseGrid.toolbar.next.isDisable = true;
    //   this.oBaseGrid.toolbar.jumpLast.isDisable = true;
    //   this.oBaseGrid.toolbar.save.isDisable = true;
    //   this.oBaseGrid.toolbar.edit.isDisable = true;
    //   this.oBaseGrid.toolbar.audit.isDisable = true;
    //   this.oBaseGrid.toolbar.delete.isDisable = true;
    //   this.oBaseGrid.toolbar.insert.isDisable = true;
    //   this.oBaseGrid.toolbar.edit.isDisable = true;
    //   this.oBaseGrid.toolbar.refresh.isDisable = true;
    //   this.oBaseGrid.toolbar.audit.isDisable = true;
    // }
  }

  private setTempToolbarStatusUnDisabled(
    p: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    // if (this.toolbarStatusBak) {
    //   this.oBaseGrid.toolbar = this.toolbarStatusBak;
    //   this.toolbarStatusBak = null;
    // }
  }

  // 处理组件协调
  public sendEventCoordination(
    type: N_oSetupPanel.N_comps.T_eventCoordinationToolbar
  ) {
    const r = this.TCoordination.sendEventCoordination(
      type,
      this.oBasePanel.$bus
    )
      .then(([b, msg]) => {})
      .catch(msg => {
        console.error(msg);
        // this.oBasePanel.$msg(msg);
      });
  }

  // 从getfun api里新增加的属性，用此决定一个功能的i18n字段，字段的m2o的来源表描述字段是否是国际化字段
  public isI18nField(fieldName: string): boolean {
    if (this.oBasePanel.config?.funI18nFields) {
      return this.oBasePanel.config.funI18nFields.indexOf(fieldName) !== -1;
    }
    return false;
  }

  public addInitFilter(filter: ifs.I_fv[]) {
    const oBasePanel = this.oBasePanel;
    oBasePanel.initFilter = filter;
  }

  /**
   * 处理标准按钮前后事件
   * @param actionName 按钮名
   * @param callback 按钮回调函数（注：必须是promise）
   */
  public handleBtnActions(
    actionName: string,
    callback: () => Promise<boolean>
  ) {
    const actionsCfg = this.oBasePanel.actionsCfg;
    const name = actionName.replace(/^./, match => match.toUpperCase());

    if (actionsCfg[`before${name}`]) {
      const bParams = this.getSelectedData();
      bParams.title = actionsCfg[`before${name}`];
      bParams.from = `before${name}`;
      this.doEvent(actionsCfg[`before${name}`], bParams).then(_ => {
        if (_) {
          callback().then(res => {
            if (res && actionsCfg[`after${name}`]) {
              const aParams = this.getSelectedData();
              aParams.title = actionsCfg[`after${name}`];
              aParams.from = `after${name}`;
              this.doEvent(actionsCfg[`after${name}`], aParams);
            }
          });
        }
      });
    } else {
      callback().then(r => {
        if (r && actionsCfg[`after${name}`]) {
          const aParams = this.getSelectedData();
          aParams.title = actionsCfg[`after${name}`];
          aParams.from = `after${name}`;
          this.doEvent(actionsCfg[`after${name}`], aParams);
        }
      });
    }
  }
}
interface I_command extends T_command {}
export { I_command, T_command };
